﻿using System;
using System.Net;
using System.Net.Sockets;

namespace LNet
{
    public abstract class TcpServer
    {
        public Socket _worksocket;//当前套接字
        private Message _msg = new Message();

        public TcpServer()
        {

        }
        public TcpServer(Socket soc)
        {
          
            AsynRecive();
        }

        protected void AsynRecive()
        {
            if (_worksocket == null || _worksocket.Connected == false) return;
            _worksocket.BeginReceive(_msg.Data, _msg.StartIndex, _msg.RemainSize, SocketFlags.None, ReceiveCallback, null);
        }

        public IPAddress GetIPAddress()
        {

            if (_worksocket == null)
            {
                return null;
            }
            return ((IPEndPoint)_worksocket.RemoteEndPoint).Address;



        }

        public EndPoint IPPORT
        {
            get
            {
                if (_worksocket != null)
                    return _worksocket.RemoteEndPoint;
                return null;

            }
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            if (_worksocket == null || _worksocket.Connected == false) return;
            int count = 0;
            try//该try可以检测客户端是否断开了连接
            {
                count = _worksocket.EndReceive(ar);//接收数据结束，返回接收到的长度
            }
            catch (Exception)
            {
                DisConnectedHandler();
                return;
            }
            if (count == 0)
            {
                System.Diagnostics.Debug.WriteLine("接收到数据长度 = 0");
                // client.UpdateLogoutTime();
                DisConnectedHandler();
                return;
            }

            try//捕获处理数据时发生的错误
            {
                _msg.ParseFromClientMessage(count, ReceiveHandler);
            }
            catch (Exception e)
            {
                //throw e;//捕获到异常时抛出异常，便于定位解决
                ExceptionHandler(e);
            }
            AsynRecive();
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public virtual bool AsynSend(Response packet)
        {
            if (packet == null) return false;
            if (_worksocket == null || !_worksocket.Connected)
            {
                return false;
            }
            try
            {
                byte[] bytes = Message.ServerPackData(packet);
                _worksocket.Send(bytes);
                return true;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("无法发送消息,已做断开处理。异常描述:" + e.Message);
                DisConnectedHandler();
                return false;
            }
        }


        /// <summary>
        /// 子类实现具体逻辑
        /// </summary>
        /// <param name="request"></param>
        protected abstract void ReceiveHandler(Request request);

        /// <summary>
        /// 暂时关闭了连接，可能只是网络波动，超过20s后，才真正断开
        /// </summary>
        //public abstract void TemporalDisConnectedHandler();


        /// <summary>
        /// 超过20s后的断开连接
        /// </summary>
        public abstract void DisConnectedHandler();

        /// <summary>
        /// 关闭由Client调用
        /// </summary>
        public void Close()
        {
            if (_worksocket != null)
            {
                //worksocket.Shutdown(SocketShutdown.Both);
                _worksocket.Close();
                _worksocket = null;
            }
        }

        public abstract void ExceptionHandler(Exception e);

        /// <summary>
        /// 判断当前连接是否
        /// </summary>
        public bool IsConnected
        {
            get
            {
                return _worksocket != null;
            }
        }


    }

}
